package cn.gemiman.daoyi.module.cms.service.blogmessage;

import cn.gemiman.daoyi.framework.common.enums.UserTypeEnum;
import cn.gemiman.daoyi.framework.common.pojo.PageResult;
import cn.gemiman.daoyi.framework.common.util.object.BeanUtils;
import cn.gemiman.daoyi.framework.common.util.servlet.ServletUtils;
import cn.gemiman.daoyi.framework.ip.core.Area;
import cn.gemiman.daoyi.framework.ip.core.utils.IPUtils;
import cn.gemiman.daoyi.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.gemiman.daoyi.module.cms.controller.admin.blogmessage.vo.BlogMessagePageReqVO;
import cn.gemiman.daoyi.module.cms.controller.admin.blogmessage.vo.BlogMessageSaveReqVO;
import cn.gemiman.daoyi.module.cms.dal.dataobject.blogmessage.BlogMessageDO;
import cn.gemiman.daoyi.module.cms.dal.dataobject.tagdictionary.TagDictionaryDO;
import cn.gemiman.daoyi.module.cms.dal.mysql.blogmessage.BlogMessageMapper;
import cn.gemiman.daoyi.module.cms.dal.mysql.tagdictionary.TagDictionaryMapper;
import cn.gemiman.daoyi.module.member.api.user.MemberUserApi;
import cn.gemiman.daoyi.module.member.api.user.dto.MemberUserRespDTO;
import cn.gemiman.daoyi.module.system.api.user.AdminUserApi;
import cn.gemiman.daoyi.module.system.api.user.dto.AdminUserRespDTO;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import static cn.gemiman.daoyi.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.gemiman.daoyi.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.gemiman.daoyi.module.cms.enums.ErrorCodeConstants.BLOG_MESSAGE_NOT_EXISTS;
import static cn.gemiman.daoyi.module.cms.enums.ErrorCodeConstants.BLOG_MESSAGE_NOT_SELF;

/**
 * 留言 Service 实现类
 *
 * @author 道一源码
 */
@Service
@Validated
public class BlogMessageServiceImpl implements BlogMessageService {

    @Resource
    private BlogMessageMapper blogMessageMapper;
    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private MemberUserApi memberUserApi;
    @Resource
    private TagDictionaryMapper tagDictionaryMapper;

    @Override
    public Long createBlogMessage(BlogMessageSaveReqVO createReqVO) {
        String clientIP = ServletUtils.getClientIP();
        createReqVO.setCreatorIp(clientIP);
        if (CharSequenceUtil.isNotBlank(clientIP)) {
            Area area = IPUtils.getArea(clientIP);
            if (null != area) {
                createReqVO.setCreatorCity(area.getName());
            }
        }
        // 插入
        BlogMessageDO blogMessage = BeanUtils.toBean(createReqVO, BlogMessageDO.class);
        if (UserTypeEnum.ADMIN.getValue().equals(blogMessage.getUserType())) {
            AdminUserRespDTO checkedData = adminUserApi.getUser(blogMessage.getUserId()).getCheckedData();
            blogMessage.setUserNickname(checkedData.getNickname());
            blogMessage.setUserAvatar(checkedData.getAvatar());
        }
        if (UserTypeEnum.MEMBER.getValue().equals(blogMessage.getUserType())) {
            MemberUserRespDTO checkedData = memberUserApi.getUser(blogMessage.getUserId()).getCheckedData();
            blogMessage.setUserNickname(checkedData.getNickname());
            blogMessage.setUserAvatar(checkedData.getAvatar());
        }
        blogMessageMapper.insert(blogMessage);
        if (CharSequenceUtil.isNotBlank(createReqVO.getTag())) {
            if (!tagDictionaryMapper.exists(new LambdaQueryWrapperX<TagDictionaryDO>().eq(TagDictionaryDO::getName, createReqVO.getTag()))) {
                tagDictionaryMapper.insert(new TagDictionaryDO().setName(createReqVO.getTag()).setArticleCount(1L));
            } else {
                tagDictionaryMapper.updateArticleCount(createReqVO.getTag());
            }
        }
        // 返回
        return blogMessage.getId();
    }

    @Override
    public void updateBlogMessage(BlogMessageSaveReqVO updateReqVO) {
        // 校验存在
        validateBlogMessageExists(updateReqVO.getId());
        // 更新
        blogMessageMapper.updateById(new BlogMessageDO()
                .setId(updateReqVO.getId())
                .setMessage(updateReqVO.getMessage())
                .setFontSize(updateReqVO.getFontSize())
                .setFontWeight(updateReqVO.getFontWeight())
                .setBgColor(updateReqVO.getBgColor())
                .setBgUrl(updateReqVO.getBgUrl())
                .setTag(updateReqVO.getTag())
                .setReferTo(updateReqVO.getReferTo())
        );
        if (CharSequenceUtil.isNotBlank(updateReqVO.getTag())) {
            if (!tagDictionaryMapper.exists(new LambdaQueryWrapperX<TagDictionaryDO>().eq(TagDictionaryDO::getName, updateReqVO.getTag()))) {
                tagDictionaryMapper.insert(new TagDictionaryDO().setName(updateReqVO.getTag()).setArticleCount(1L));
            } else {
                tagDictionaryMapper.updateArticleCount(updateReqVO.getTag());
            }
        }
    }

    @Override
    public void updateBlogMessage(BlogMessageSaveReqVO updateReqVO, boolean checkSelf) {
        // 校验存在
        BlogMessageDO messageExists = validateBlogMessageExists(updateReqVO.getId());
        if (checkSelf && (!UserTypeEnum.MEMBER.getValue().equals(messageExists.getUserType()) || !ObjUtil.equals(messageExists.getUserId(), getLoginUserId()))) {
            throw exception(BLOG_MESSAGE_NOT_SELF);
        }
        // 更新
        blogMessageMapper.updateById(new BlogMessageDO()
                .setId(updateReqVO.getId())
                .setMessage(updateReqVO.getMessage())
                .setFontSize(updateReqVO.getFontSize())
                .setFontWeight(updateReqVO.getFontWeight())
                .setBgColor(updateReqVO.getBgColor())
                .setBgUrl(updateReqVO.getBgUrl())
                .setTag(updateReqVO.getTag())
                .setReferTo(updateReqVO.getReferTo())
        );
        if (CharSequenceUtil.isNotBlank(updateReqVO.getTag())) {
            if (!tagDictionaryMapper.exists(new LambdaQueryWrapperX<TagDictionaryDO>().eq(TagDictionaryDO::getName, updateReqVO.getTag()))) {
                tagDictionaryMapper.insert(new TagDictionaryDO().setName(updateReqVO.getTag()).setArticleCount(1L));
            } else {
                tagDictionaryMapper.updateArticleCount(updateReqVO.getTag());
            }
        }
    }

    @Override
    public void deleteBlogMessage(Long id) {
        // 校验存在
        validateBlogMessageExists(id);
        // 删除
        blogMessageMapper.deleteById(id);
    }

    @Override
    public void deleteBlogMessage(Long id, boolean checkSelf) {
        // 校验存在
        BlogMessageDO messageExists = validateBlogMessageExists(id);
        if (checkSelf && (!UserTypeEnum.MEMBER.getValue().equals(messageExists.getUserType()) || !ObjUtil.equals(messageExists.getUserId(), getLoginUserId()))) {
            throw exception(BLOG_MESSAGE_NOT_SELF);
        }
        // 删除
        blogMessageMapper.deleteById(id);
    }

    private BlogMessageDO validateBlogMessageExists(Long id) {
        BlogMessageDO blogMessageDO = blogMessageMapper.selectById(id);
        if (blogMessageDO == null) {
            throw exception(BLOG_MESSAGE_NOT_EXISTS);
        }
        return blogMessageDO;
    }

    @Override
    public BlogMessageDO getBlogMessage(Long id) {
        return blogMessageMapper.selectById(id);
    }

    @Override
    public PageResult<BlogMessageDO> getBlogMessagePage(BlogMessagePageReqVO pageReqVO) {
        return blogMessageMapper.selectPage(pageReqVO);
    }

}
